package com.bt7274.controller;


import com.bt7274.grace.result.GraceJSONResult;
import com.bt7274.pojo.BtTransaction;
import com.bt7274.pojo.InvitationCode;
import com.bt7274.pojo.vo.InvitationCodeVO;
import com.bt7274.service.InvitationCodeService;
import com.bt7274.service.UserExpService;
import com.bt7274.mapper.BtTransactionMapper;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;

import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;


/**
 * 邀请码控制器
 */
@Slf4j
@RestController
@RequestMapping("/api/invitationCode")
@Tag(name = "邀请码管理", description = "邀请码生成、查询、验证" )
public class InvitationCodeController {

    @Autowired
    private InvitationCodeService invitationCodeService;

    @Autowired
    private UserExpService userExpService;

    @Autowired
    private BtTransactionMapper btTransactionMapper;

    private static final int INVITATION_CODE_COST = 100; // 生成邀请码需要消耗的BT币数量

    /**
     * 生成邀请码
     *
     * @param request:
     * @param expiresHours:
     * @return GraceJSONResult
     * @author galland
     */
    @PostMapping("/generate")
    @Operation(summary = "生成邀请码", description = "用户生成邀请码，消耗BT币")
    public GraceJSONResult generateInvitationCode(HttpServletRequest request, @RequestParam(defaultValue = "48") Integer expiresHours) {
        try {
            HttpSession session = request.getSession(false);
            if (session == null) {
                return GraceJSONResult.errorMsg("用户未登录");
            }

            String userId = (String) session.getAttribute("userId");
            if (userId == null) {
                return GraceJSONResult.errorMsg("用户未登录");
            }

            //检查用户权限
            if (!invitationCodeService.canGenerateInvitationCode(userId)) {
                return GraceJSONResult.errorMsg("用户权限不足，无法生成邀请码");
            }

            //检查BT币是否够生成邀请码
            if (!userExpService.hasSufficientBt(userId, INVITATION_CODE_COST)) {
                return GraceJSONResult.errorMsg("BT币不足，生成邀请码需要" + INVITATION_CODE_COST + "BT币");
            }

            //生成邀请码
            InvitationCode invitationCode = invitationCodeService.generateInvitationCode(userId, expiresHours);
            
            //扣除BT币
            boolean deductSuccess = userExpService.updateBt(userId, -INVITATION_CODE_COST);
            if (!deductSuccess) {
                return GraceJSONResult.errorMsg("扣除BT币失败");
            }

            //记录BT币变动
            BtTransaction transaction = new BtTransaction();
            transaction.setId(UUID.randomUUID().toString().replace("-", ""));
            transaction.setUserId(userId);
            transaction.setPoints(-INVITATION_CODE_COST);
            transaction.setType("INVITATION_CODE");
            transaction.setRuleId("INVITATION");
            transaction.setDescription("生成邀请码");
            transaction.setCreatedTime(LocalDateTime.now());
            btTransactionMapper.insert(transaction);

            log.info("用户 {} 生成邀请码: {}", userId, invitationCode.getCode());
            return GraceJSONResult.ok(invitationCode);
        }catch (Exception e) {
            log.error(e.getMessage(), e);
            return GraceJSONResult.errorMsg(e.getMessage());
        }
    }

    /**
     * 获取我的邀请码列表
     *
     * @param request:
     * @return GraceJSONResult
     * @author galland
     */
    @GetMapping("/my-codes")
    @Operation(summary = "获取我的邀请码", description = "获取当前用户创建的邀请码列表")
    public GraceJSONResult getMyCodes(HttpServletRequest request) {
        try{
            HttpSession session = request.getSession(false);
            if (session == null) {
                return GraceJSONResult.errorMsg("用户未登录");
            }

            String userId = (String) session.getAttribute("userId");
            if (userId == null) {
                return GraceJSONResult.errorMsg("用户未登录");
            }

            List<InvitationCodeVO> codes = invitationCodeService.getUserInvitationCodes(userId);
            return GraceJSONResult.ok(codes);
        }catch (Exception e) {
            log.error(e.getMessage(), e);
            return GraceJSONResult.errorMsg(e.getMessage());
        }
    }

    /**
     * 验证邀请码
     *
     * @param code: 邀请码
     * @return GraceJSONResult
     * @author galland
     */
    @GetMapping("/validate/{code}")
    @Operation(summary = "验证邀请码", description = "验证邀请码是否有效")
    public GraceJSONResult validateInvitationCode(@PathVariable String code) {
        try {
            boolean isValid = invitationCodeService.validateInvitationCode(code);
            if (isValid) {
                return GraceJSONResult.ok();
            } else {
                return GraceJSONResult.errorMsg("邀请码无效");
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return GraceJSONResult.errorMsg(e.getMessage());
        }

    }

    /**
     * 获取邀请码详情
     *
     * @param code:
     * @return GraceJSONResult
     * @author galland
     */
    @GetMapping("/detail/{code}")
    @Operation(summary = "获取邀请码详情", description = "获取邀请码的详细信息")
    public GraceJSONResult getInvitationCodeDetail(@PathVariable String code) {
        try{
            InvitationCode invitationCode = invitationCodeService.getByCode(code);
            if (invitationCode == null) {
                return GraceJSONResult.errorMsg("邀请码不存在");
            }
            return GraceJSONResult.ok(invitationCode);
        }catch (Exception e) {
            log.error(e.getMessage(), e);
            return GraceJSONResult.errorMsg(e.getMessage());
        }
    }

    /**
     * 清理过期邀请码 （管理员权限）
     *
     * @param :
     * @return GraceJSONResult
     * @author galland
     */
    @DeleteMapping("/clean-expired")
    @Operation(summary = "清理过期邀请码", description = "清理所有过期的邀请码")
    public GraceJSONResult cleanExpiredCode(){
        try{
            int count = invitationCodeService.cleanExpiredCodes();
            return GraceJSONResult.ok(count);
        }catch (Exception e) {
            log.error(e.getMessage(), e);
            return GraceJSONResult.errorMsg(e.getMessage());
        }
    }
}
